﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;

namespace Xceed.Silverlight.DataGrid
{
  internal class UpdateTransitionLayout : ILayout, ITransitionLayout
  {
    public ILayoutContainer Owner { get; private set; }
    public ILayout OldLayout { get; private set; }
    public ILayout NewLayout { get; private set; }

    public UpdateTransitionLayout( ILayoutContainer owner, ILayout oldLayout, ILayout newLayout )
    {
      if( oldLayout == null )
        throw new ArgumentNullException( "oldLayout" );

      if( newLayout == null )
        throw new ArgumentNullException( "newLayout" );

      if( owner == null )
        throw new ArgumentNullException( "owner" );

      this.Owner = owner;
      this.OldLayout = oldLayout;
      this.NewLayout = newLayout;
      m_addedElements = this.NewLayout.Elements.Except( this.OldLayout.Elements );
      m_removedElements = this.OldLayout.Elements.Except( this.NewLayout.Elements );
    }

    public IEnumerable<ILayoutElement> Elements
    {
      get { return this.NewLayout.Elements.Union(this.OldLayout.Elements); }
    }

    public Size DesiredSize
    {
      get { return this.NewLayout.DesiredSize; }
    }

    public Size MeasurePanel( Size availableSize )
    {
      return this.NewLayout.MeasurePanel(availableSize);
    }

    public Size ArrangePanel( Size finalSize, LayoutParameters parameters )
    {
      TransitionContext context = (parameters != null) ? parameters.TransitionContext : null;

      if( context != null )
      {
        foreach( ILayoutElement element in m_addedElements )
        {
          this.SetAnimationForItem( context, element, LayoutTransitionHelper.SetAddAnimationForItem );
        }

        foreach( ILayoutElement element in m_removedElements )
        {
          this.SetAnimationForItem( context, element, LayoutTransitionHelper.SetRemoveAnimationForItem );
        }
      }

      return this.NewLayout.ArrangePanel(finalSize, parameters);
    }

    public void SetViewportPosition( ViewportPosition position )
    {
      this.NewLayout.SetViewportPosition( position );
    }

    public ViewportInfo GetViewportInfo( Rect viewportRect )
    {
      return this.NewLayout.GetViewportInfo( viewportRect );
    }

    private void SetAnimationForItem( 
      TransitionContext context, 
      ILayoutElement element,
      Action<TransitionContext, IAnimatedLayoutElement> action )
    {
      if( element is VirtualGroupContainer )
      {
        foreach( ILayoutElement subElement in ( ( VirtualGroupContainer )element ).RenderedElements )
        {
          this.SetAnimationForItem( context, subElement, action );
        }
      }
      else
      {
        Debug.Assert( element is DependencyObject );
        Debug.Assert( element is IAnimatedLayoutElement );
        action(context, (IAnimatedLayoutElement) element);
      }
    }

    private IEnumerable<ILayoutElement> m_removedElements;
    private IEnumerable<ILayoutElement> m_addedElements;
  }
}
